/*
 * Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
 *
 * Licensed under the Mulan PSL v2.
 * You can use this file according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of the License at
 *
 *     http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
 * FOR MORE DETAILS.
 */

#pragma once

#include "highfive/H5File.hpp"

#include "DBManager/IRepository/Input/Design/ITOMVARRepository.h"
#include "DBManager/Repository/HDF5/Base/MainlyRepositoryBase.h"
SG_DBMANAGER_HDF5_NAMESPACE_OPEN
namespace TOMVAR
{
    struct IDENTITY
    {
        SG::DataStructure::Common::Id   TOMID     = 0;      ///<
        char                            PTYPE[8]  = { 0 };  ///<
        SG::DataStructure::Common::Id   PID       = 0;      ///<
        SG::DataStructure::Common::Id   FID       = 0;      ///<
        char                            PNAME[8]  = { 0 };  ///<
        SG::DataStructure::Common::Real XINIT     = 0.0;    ///<
        SG::DataStructure::Common::Real XLB       = 0.0;    ///<
        SG::DataStructure::Common::Real XUB       = 0.0;    ///<
        SG::DataStructure::Common::Real DELXV     = 0.0;    ///<
        SG::DataStructure::Common::I64  SYM_LEN   = 0;      ///<
        SG::DataStructure::Common::I64  DIS_LEN   = 0;      ///<
        SG::DataStructure::Common::I64  TOM_LEN   = 0;      ///<
        SG::DataStructure::Common::I64  SYM_POS   = 0;      ///<
        SG::DataStructure::Common::I64  DIS_POS   = 0;      ///<
        SG::DataStructure::Common::I64  TOM_POS   = 0;      ///<
        SG::DataStructure::Common::Id   DOMAIN_ID = 0;      ///<
    };
};  // namespace TOMVAR
SG_DBMANAGER_HDF5_NAMESPACE_CLOSE
template <>
inline HighFive::DataType HighFive::create_datatype<SG::DBManager::HDF5::TOMVAR::IDENTITY> ()
{
    HighFive::CompoundType compoundType = { { "TOMID", HighFive::create_datatype<SG::DataStructure::Common::Id> () },
                                            { "PTYPE", HighFive::create_datatype<char[8]> (), 1, true },
                                            { "PID", HighFive::create_datatype<SG::DataStructure::Common::Id> () },
                                            { "FID", HighFive::create_datatype<SG::DataStructure::Common::Id> () },
                                            { "PNAME", HighFive::create_datatype<char[8]> (), 1, true },
                                            { "XINIT", HighFive::create_datatype<SG::DataStructure::Common::Real> () },
                                            { "XLB", HighFive::create_datatype<SG::DataStructure::Common::Real> () },
                                            { "XUB", HighFive::create_datatype<SG::DataStructure::Common::Real> () },
                                            { "DELXV", HighFive::create_datatype<SG::DataStructure::Common::Real> () },
                                            { "SYM_LEN", HighFive::create_datatype<SG::DataStructure::Common::I64> () },
                                            { "DIS_LEN", HighFive::create_datatype<SG::DataStructure::Common::I64> () },
                                            { "TOM_LEN", HighFive::create_datatype<SG::DataStructure::Common::I64> () },
                                            { "SYM_POS", HighFive::create_datatype<SG::DataStructure::Common::I64> () },
                                            { "DIS_POS", HighFive::create_datatype<SG::DataStructure::Common::I64> () },
                                            { "TOM_POS", HighFive::create_datatype<SG::DataStructure::Common::I64> () },
                                            { "DOMAIN_ID", HighFive::create_datatype<SG::DataStructure::Common::Id> () } };
    return compoundType;
}

template <>
inline HighFive::DataType HighFive::create_datatype<SG::DataStructure::FEM::TOMVARData::DISCRETEData> ()
{
    HighFive::CompoundType ct = { { "DVID", HighFive::create_datatype<SG::DataStructure::Common::Id> () } };
    return ct;
}
template <>
inline HighFive::DataType HighFive::create_datatype<SG::DataStructure::FEM::TOMVARData::SYMPLANEData> ()
{
    HighFive::CompoundType ct = { { "CID", HighFive::create_datatype<SG::DataStructure::Common::Id> () },
                                  { "MS1", HighFive::create_datatype<SG::DataStructure::Common::I64> () },
                                  { "MS2", HighFive::create_datatype<SG::DataStructure::Common::I64> () },
                                  { "MS3", HighFive::create_datatype<SG::DataStructure::Common::I64> () },
                                  { "CSM", HighFive::create_datatype<SG::DataStructure::Common::I64> () },
                                  { "NCSM", HighFive::create_datatype<SG::DataStructure::Common::I64> () } };
    return ct;
}
template <>
inline HighFive::DataType HighFive::create_datatype<SG::DataStructure::FEM::TOMVARData::TOMVARIDData> ()
{
    HighFive::CompoundType ct = { { "TID", HighFive::create_datatype<SG::DataStructure::Common::Id> () },
                                  { "C0", HighFive::create_datatype<SG::DataStructure::Common::Real> () },
                                  { "C1", HighFive::create_datatype<SG::DataStructure::Common::Real> () } };
    return ct;
}
SG_DBMANAGER_HDF5_NAMESPACE_OPEN
class TOMVARRepository : public ITOMVARRepository, public SG::DBManager::HDF5::MainlyRepositoryBase<SG::DataStructure::FEM::TOMVARData>
{
    using MainStruct   = SG::DataStructure::FEM::TOMVARData;
    using SubStructDIS = SG::DataStructure::FEM::TOMVARData::DISCRETEData;
    using SubStructSYM = SG::DataStructure::FEM::TOMVARData::SYMPLANEData;
    using SubStructTOM = SG::DataStructure::FEM::TOMVARData::TOMVARIDData;

    using NasMainStruct = SG::DBManager::HDF5::TOMVAR::IDENTITY;

  public:
    explicit TOMVARRepository (HDF5Database& database);

    enum DATASET : std::uint8_t
    {
        MainDataset,
        IndexDataset,
        SubDataset_DIS,
        SubDataset_SYM,
        SubDataset_TOM
    };

    /**
     * @brief   : 初始化表数据
     * @author  : wuxingchuang
     */
    void InitialDatasetInfo () override;

    /**
     * @brief   : 将缓存数据转储到文件内
     */
    void DumpWriteCahce () override;

    /**
     * @brief   : 加载文件数据至缓存
     * @param   : loadIndex
     */
    std::vector<DataType>* LoadReadCache (std::size_t loadIndex) override;

    /**
     * @brief   : 对数据进行排序
     */
    void SortData () override;

    /**
     * @brief   : 获取所有数据
     */
    std::vector<MainStruct> GetAllData () override;

    /**
     * @brief   : 将自己的数据转存为nastran的数据结构
     */
    void OwnToNastran (std::vector<MainStruct>&         own,
                       std::vector<NasMainStruct>& _OUT IDENTITYData,
                       std::vector<SubStructDIS>& _OUT  subDataDIS,
                       std::vector<SubStructSYM>& _OUT  subDataSYM,
                       std::vector<SubStructTOM>& _OUT  subDataTOM,

                       bool isSort = false);

    /**
     * @brief   : 将NASTRAN的数据转存为自己的数据结构
     * @param   : IDENTITYData
     * @param   : subData
     * @param   : own
     */
    void NastranToOwn (std::vector<NasMainStruct>&   IDENTITYData,
                       std::vector<SubStructDIS>&    subDataDIS,
                       std::vector<SubStructSYM>&    subDataSYM,
                       std::vector<SubStructTOM>&    subDataTOM,
                       std::vector<MainStruct>& _OUT own);
};
SG_DBMANAGER_HDF5_NAMESPACE_CLOSE
